<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="egtoE" id="egtoE"><span data-lake-id="u2249b938" id="u2249b938">典型回答</span></h1>
  <p data-lake-id="ue06fd16e" id="ue06fd16e"><br></p>
  <p data-lake-id="ua2406d5b" id="ua2406d5b"><span data-lake-id="u08805fa0" id="u08805fa0">数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列，这些操作要么全部执行，要么全部不执行，是一个不可分割的工作单位。 事务由事务开始与事务结束之间执行的全部数据库操作组成。</span></p>
  <p data-lake-id="u8142965a" id="u8142965a"><span data-lake-id="uc4e0e4f8" id="uc4e0e4f8">​</span><br></p>
  <p data-lake-id="ud8545c83" id="ud8545c83"><span data-lake-id="uf764abe9" id="uf764abe9">并非任意的对数据库的操作序列都是数据库事务。事务应该具有4个属性：原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。</span></p>
  <ul list="u6d2666df">
   <li fid="uc57721f8" data-lake-id="u97ee16b9" id="u97ee16b9"><span data-lake-id="u29f53f78" id="u29f53f78">原子性（Atomicity）：事务作为一个整体被执行，包含在其中的对数据库的操作要么全部被执行，要么都不执行。</span></li>
   <li fid="uc57721f8" data-lake-id="u128bdc74" id="u128bdc74"><span data-lake-id="ucc02d3c0" id="ucc02d3c0">一致性（Consistency）：事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。</span></li>
   <li fid="uc57721f8" data-lake-id="u27fece96" id="u27fece96"><span data-lake-id="u1dca56a5" id="u1dca56a5">隔离性（Isolation）：多个事务并发执行时，一个事务的执行不应影响其他事务的执行。</span></li>
   <li fid="uc57721f8" data-lake-id="u1d90a432" id="u1d90a432"><span data-lake-id="u8fb5dee2" id="u8fb5dee2">持久性（Durability）：一个事务一旦提交，他对数据库的修改应该永久保存在数据库中。</span></li>
  </ul>
  <p data-lake-id="u377f7487" id="u377f7487"><br></p>
  <h1 data-lake-id="eqoxJ" id="eqoxJ"><span data-lake-id="uced2d44d" id="uced2d44d">扩展知识</span></h1>
  <p data-lake-id="uf5165e6e" id="uf5165e6e"><br></p>
  <h2 data-lake-id="chd0V" id="chd0V"><span data-lake-id="u31d1fa7c" id="u31d1fa7c">如何理解ACID</span></h2>
  <p data-lake-id="u8513c3c0" id="u8513c3c0"><br></p>
  <p data-lake-id="u844f6a3e" id="u844f6a3e"><span data-lake-id="u959bc798" id="u959bc798">举例说明一下，用一个常用的“A账户向B账号汇钱”的例子来说明如何通过数据库事务保证数据的准确性和完整性。熟悉关系型数据库事务的都知道从帐号A到帐号B需要6个操作：</span></p>
  <p data-lake-id="ud231940e" id="ud231940e"><span data-lake-id="uf77e7366" id="uf77e7366">​</span><br></p>
  <p data-lake-id="uf57ad165" id="uf57ad165"><span data-lake-id="u3377363e" id="u3377363e">1、从A账号中把余额读出来（500）。 2、对A账号做减法操作（500-100）。 3、把结果写回A账号中（400）。 4、从B账号中把余额读出来（500）。 5、对B账号做加法操作（500+100）。 6、把结果写回B账号中（600）。</span></p>
  <p data-lake-id="ub9456b6d" id="ub9456b6d"><span data-lake-id="ua4159652" id="ua4159652">​</span><br></p>
  <h3 data-lake-id="b8oy1" id="b8oy1"><span data-lake-id="u7eec6448" id="u7eec6448">原子性</span></h3>
  <p data-lake-id="ueb494309" id="ueb494309"><span data-lake-id="u411374cd" id="u411374cd">保证1-6所有过程要么都执行，要么都不执行。一旦在执行某一步骤的过程中发生问题，就需要执行回滚操作。 假如执行到第五步的时候，B账户突然不可用（比如被注销），那么之前的所有操作都应该回滚到执行事务之前的状态。</span></p>
  <h3 data-lake-id="NoZ6e" id="NoZ6e"><span data-lake-id="u97ed1636" id="u97ed1636">一致性</span></h3>
  <p data-lake-id="ub66ac334" id="ub66ac334"><span data-lake-id="uea768f46" id="uea768f46">在转账之前，A和B的账户中共有500+500=1000元钱。在转账之后，A和B的账户中共有400+600=1000元。也就是说，数据的状态在执行该事务操作之后从一个状态改变到了另外一个状态。同时一致性还能保证账户余额不会变成负数等。</span></p>
  <h3 data-lake-id="ikfeS" id="ikfeS"><span data-lake-id="uc062139d" id="uc062139d">隔离性</span></h3>
  <p data-lake-id="ua155c3fd" id="ua155c3fd"><span data-lake-id="ub41826df" id="ub41826df">在A向B转账的整个过程中，只要事务还没有提交（commit），查询A账户和B账户的时候，两个账户里面的钱的数量都不会有变化。 如果在A给B转账的同时，有另外一个事务执行了C给B转账的操作，那么当两个事务都结束的时候，B账户里面的钱应该是A转给B的钱加上C转给B的钱再加上自己原有的钱。</span></p>
  <h3 data-lake-id="xFhIB" id="xFhIB"><span data-lake-id="u474c8708" id="u474c8708">持久性</span></h3>
  <p data-lake-id="uc901abe4" id="uc901abe4"><span data-lake-id="u3c3fa33d" id="u3c3fa33d">一旦转账成功（事务提交），两个账户的里面的钱就会真的发生变化（会把数据写入数据库做持久化保存）！</span></p>
  <p data-lake-id="u02a987f3" id="u02a987f3"><span data-lake-id="u6d7451fd" id="u6d7451fd">​</span><br></p>
  <h2 data-lake-id="EfQQp" id="EfQQp"><span data-lake-id="ub01d187d" id="ub01d187d">数据库事务存在的异常读现象</span></h2>
  <p data-lake-id="u2cd71416" id="u2cd71416"><br></p>
 </body>
</html>